<?php

namespace slinks\extensions\action\core;

use slinks\extensions\action\interceptor\InterceptorStack;
use slinks\core\HttpFoundation\IIRequest;
use slinks\extensions\action\core\IActionProxy;
use slinks\extensions\action\core\IActionContext;
use slinks\core\DependencyInjection\ParameterBag\ParameterBagInterface;
use slinks\extensions\action\core\IActionInvocation;

/**
 * Default IActionInvocation
 * @author Navid Mitchell
 *
 */
class ActionInvocation implements IActionInvocation {
    /* @var $interceptors InterceptorStack  */

    private $interceptors;

    /* @var $request IActionContext */
    private $actionContext;

    /* @var $actionProxy IActionProxy */
    private $actionProxy;
    private $currentInterceptorIndex = 0;
    private $returnValue;

    function __construct(IActionProxy $actionProxy, InterceptorStack $interceptors, IActionContext $actionContext) {
        $this->actionProxy = $actionProxy;
        $this->interceptors = $interceptors;
        $this->actionContext = $actionContext;
    }

    /**
     * @return the IActionContext for use with this proxy
     */
    public function getActionContext(){
        return $this->actionContext;
    }

    /**
     * @return IActionProxy the action proxy for the action being invoked.
     */
    public function getActionProxy() {
        return $this->actionProxy;
    }

    /**
     * Invoke the next interceptor in the chain.
     * @return string return code with the result of this invocation.
     */
    public function invoke() {

        // This method will be caled recursively by the interceptors.
        if ($this->currentInterceptorIndex < count($this->interceptors)) {

            /* @var $interceptor IActionInterceptor */
            $interceptor = $this->interceptors[$this->currentInterceptorIndex];
            $this->currentInterceptorIndex++;

            $interceptor->intercept($this);
        }
    }

    /**
     * The return value for the Invocation.
     * @return mixed
     */
    public function getReturnValue() {
        return $this->returnValue;
    }

    /**
     * Set the return value.
     *
     * @param mixed $returnValue
     */
    public function setReturnValue($returnValue) {
        $this->returnValue = $returnValue;
    }

}